package com.hoow.shakoow.ai.network

import com.hoow.shakoow.ai.data.*
import com.hoow.shakoow.extend.toFullUrlPath
import okhttp3.MultipartBody
import retrofit2.Call
import retrofit2.Callback
import retrofit2.Response
import retrofit2.http.Part
import retrofit2.http.QueryMap
import java.lang.RuntimeException
import kotlin.coroutines.resume
import kotlin.coroutines.resumeWithException
import kotlin.coroutines.suspendCoroutine

object ApiAiNetwork {

    private val mApiAiService = ApiAiServiceCreator.create<ApiAiService>()

    /**
     * app-获取APP更新版本
     *
     * @param reqAiBase body
     */
    suspend fun getAiAppVersion(reqAiBase: ReqAiBase) =
        mApiAiService.getAppVersion(
            ApiAiPathUrl.PATH_APP_VERSION.toFullUrlPath(),
            reqAiBase
        ).await()

    /**
     * app-获取APP配置
     *
     * @param reqAiBase body
     */
    suspend fun getAppConfig(reqAiBase: ReqAiBase) =
        mApiAiService.getAppConfig(
            ApiAiPathUrl.PATH_APP_CONFIG.toFullUrlPath(),
            reqAiBase
        ).await()

    /**
     * 登录-广告id登录
     *
     * @param reqAiBase body
     */
    suspend fun loginByAdvertId(reqAiBase: ReqAiBase) =
        mApiAiService.loginByAdvertId(
            ApiAiPathUrl.PATH_LOGIN_BY_ADVERT_ID.toFullUrlPath(),
            reqAiBase
        ).await()

    /**
     * 用户-获取用户详情
     *
     * @param reqAiBase body
     */
    suspend fun getUserInfo(reqAiBase: ReqAiBase) =
        mApiAiService.getUserInfo(
            ApiAiPathUrl.PATH_USER_INFO.toFullUrlPath(),
            ApiAiHeaderMap(),
            reqAiBase
        ).await()

    /**
     * 用户-获取用户详情 根据id
     *
     * @param reqAiBase body
     */
    suspend fun getUserInfoByUserId(reqAiBase: ReqAiBase) =
        mApiAiService.getUserInfoByUserId(
            ApiAiPathUrl.PATH_USER_INFO_BY_USERID.toFullUrlPath(),
            ApiAiHeaderMap(),
            reqAiBase
        ).await()

    /**
     * 工具-上传文件
     *
     * @param map 参数
     * @param file body
     */
    suspend fun uploadFile(
        @QueryMap map: Map<String, String>,
        @Part file: MultipartBody.Part,
    ) =
        mApiAiService.uploadFile(
            ApiAiPathUrl.PATH_UPLOAD_FILE.toFullUrlPath(),
            ApiAiHeaderMap(),
            map,
            file
        ).await()

    /**
     * 设置用户昵称与性别
     *
     * @param reqSetUserName body
     */
    suspend fun setUserName(reqSetUserName: ReqSetUserName) =
        mApiAiService.setUserName(
            ApiAiPathUrl.PATH_SET_USER_NAME.toFullUrlPath(),
            ApiAiHeaderMap(),
            reqSetUserName
        ).await()

    /**
     * 设置用户头像
     *
     * @param reqSetUserHeadImg body
     */
    suspend fun setUserHeadImg(reqSetUserHeadImg: ReqSetUserHeadImg) =
        mApiAiService.setUserHeadImg(
            ApiAiPathUrl.PATH_SET_USER_AVATAR.toFullUrlPath(),
            ApiAiHeaderMap(),
            reqSetUserHeadImg
        ).await()

    /**
     * 开始摇一摇
     *
     * @param reqAiBase body
     */
    suspend fun startShake(reqAiBase: ReqAiBase) =
        mApiAiService.startShake(
            ApiAiPathUrl.PATH_START_SHAKE.toFullUrlPath(),
            ApiAiHeaderMap(),
            reqAiBase
        ).await()

    /**
     * 摇一摇返回的用户
     *
     * @param reqGetShakeUserInfo body
     */
    suspend fun getShakeUserInfo(reqGetShakeUserInfo: ReqGetShakeUserInfo) =
        mApiAiService.getShakeUserInfo(
            ApiAiPathUrl.PATH_SHAKE_USER.toFullUrlPath(),
            ApiAiHeaderMap(),
            reqGetShakeUserInfo
        ).await()

    /**
     * 设置用户签名
     *
     * @param reqSetUserSignature body
     */
    suspend fun setUserSignature(reqSetUserSignature: ReqSetUserSignature) =
        mApiAiService.setUserSignature(
            ApiAiPathUrl.PATH_SET_USER_SIGNATURE.toFullUrlPath(),
            ApiAiHeaderMap(),
            reqSetUserSignature
        ).await()

    /**
     * 获取用户相册
     *
     * @param reqAiBase body
     */
    suspend fun getUserPhotos(reqAiBase: ReqAiBase) =
        mApiAiService.getUserPhotos(
            ApiAiPathUrl.PATH_USER_PHOTOS.toFullUrlPath(),
            ApiAiHeaderMap(),
            reqAiBase
        ).await()

    /**
     * 上传用户相册
     *
     * @param reqUploadUserPhotos body
     */
    suspend fun uploadUserPhotos(reqUploadUserPhotos: ReqUploadUserPhotos) =
        mApiAiService.uploadUserPhotos(
            ApiAiPathUrl.PATH_USER_UPLOAD_PHOTOS.toFullUrlPath(),
            ApiAiHeaderMap(),
            reqUploadUserPhotos
        ).await()

    /**
     * 删除用户相册
     *
     * @param reqDeleteUserPhotos body
     */
    suspend fun deleteUserPhotos(reqDeleteUserPhotos: ReqDeleteUserPhotos) =
        mApiAiService.deleteUserPhotos(
            ApiAiPathUrl.PATH_USER_DELETE_PHOTOS.toFullUrlPath(),
            ApiAiHeaderMap(),
            reqDeleteUserPhotos
        ).await()

    /**
     * 获取打招呼的历史
     *
     * @param reqAiBase body
     */
    suspend fun getGreetHistoryList(reqAiBase: ReqAiBase) =
        mApiAiService.getGreetsHistoryList(
            ApiAiPathUrl.PATH_GREET_HISTORY.toFullUrlPath(),
            ApiAiHeaderMap(),
            reqAiBase
        ).await()

    /**
     * shake-获取历史列表
     *
     * @param reqAiBase body
     */
    suspend fun getShakeHistoryList(reqAiBase: ReqAiBase) =
        mApiAiService.getShakeHistoryList(
            ApiAiPathUrl.PATH_SHAKE_HISTORY.toFullUrlPath(),
            ApiAiHeaderMap(),
            reqAiBase
        ).await()

    /**
     * 获取对话详情
     *
     * @param reqChatInfo body
     */
    suspend fun getChatInfo(reqChatInfo: ReqChatInfo) =
        mApiAiService.getChatInfo(
            ApiAiPathUrl.PATH_CHAT_INFO.toFullUrlPath(),
            ApiAiHeaderMap(),
            reqChatInfo
        ).await()

    /**
     * 打招呼
     *
     * @param reqToGreet body
     */
    suspend fun toGreet(reqToGreet: ReqToGreet) =
        mApiAiService.toGreet(
            ApiAiPathUrl.PATH_TO_GREET.toFullUrlPath(),
            ApiAiHeaderMap(),
            reqToGreet
        ).await()

    /**
     * 回复消息
     *
     * @param reqToReply body
     */
    suspend fun toReply(reqToReply: ReqToReply) =
        mApiAiService.toReply(
            ApiAiPathUrl.PATH_TO_REPLY.toFullUrlPath(),
            ApiAiHeaderMap(),
            reqToReply
        ).await()

    /**
     * 记录看完广告
     *
     * @param reqLookedAdvert body
     */
    suspend fun saveLookedAdvert(reqLookedAdvert: ReqLookedAdvert) =
        mApiAiService.saveLookedAdvert(
            ApiAiPathUrl.PATH_LOOKED_ADVERT.toFullUrlPath(),
            ApiAiHeaderMap(),
            reqLookedAdvert
        ).await()

    /**
     * 获取用户vip信息
     *
     * @param reqAiBase body
     */
    suspend fun getUserVipInfo(reqAiBase: ReqAiBase) =
        mApiAiService.getUserVipInfo(
            ApiAiPathUrl.PATH_GET_USER_VIP_INFO.toFullUrlPath(),
            ApiAiHeaderMap(),
            reqAiBase
        ).await()

    /**
     * 获取商品id
     *
     * @param reqAiBase body
     */
    suspend fun getPayOrderId(reqAiBase: ReqAiBase) =
        mApiAiService.getPayOrderId(
            ApiAiPathUrl.PATH_CREATE_GOOGLE_PAY_ORDER.toFullUrlPath(),
            ApiAiHeaderMap(),
            reqAiBase
        ).await()

    /**
     * 保存订单支付信息
     *
     * @param reqSavePayOrderInfo body
     */
    suspend fun savePayOrderInfo(reqSavePayOrderInfo: ReqSavePayOrderInfo) =
        mApiAiService.savePayOrderInfo(
            ApiAiPathUrl.PATH_PROCESS_GOOGLE_PAY_ORDER.toFullUrlPath(),
            ApiAiHeaderMap(),
            reqSavePayOrderInfo
        ).await()

    /**
     * 订单支付成功
     *
     * @param reqSavePayOrderInfo body
     */
    suspend fun payOrderInfoSuccess(reqSavePayOrderInfo: ReqSavePayOrderInfo) =
        mApiAiService.payOrderInfoSuccess(
            ApiAiPathUrl.PATH_SUCCESS_GOOGLE_PAY_ORDER.toFullUrlPath(),
            ApiAiHeaderMap(),
            reqSavePayOrderInfo
        ).await()

    /**
     * 消息-删除招呼记录
     *
     * @param reqDeleteGreetRecord body
     */
    suspend fun deleteGreetRecord(reqDeleteGreetRecord: ReqDeleteGreetRecord) =
        mApiAiService.deleteGreetRecord(
            ApiAiPathUrl.PATH_REMOVE_GREET_RECORD.toFullUrlPath(),
            ApiAiHeaderMap(),
            reqDeleteGreetRecord
        ).await()

    /**
     * 消息-删除摇一摇记录
     *
     * @param reqDeleteShakeRecord body
     */
    suspend fun deleteShakeRecord(reqDeleteShakeRecord: ReqDeleteShakeRecord) =
        mApiAiService.deleteShakeRecord(
            ApiAiPathUrl.PATH_REMOVE_SHAKE_RECORD.toFullUrlPath(),
            ApiAiHeaderMap(),
            reqDeleteShakeRecord
        ).await()

    /**
     * 消息-阅读打招呼消息
     *
     * @param reqReadGreetMsg body
     */
    suspend fun readGreetMsg(reqReadGreetMsg: ReqReadGreetMsg) =
        mApiAiService.readGreetMsg(
            ApiAiPathUrl.PATH_READ_GREET_MSG.toFullUrlPath(),
            ApiAiHeaderMap(),
            reqReadGreetMsg
        ).await()

    /**
     * 消息-获取用户是否有新消息
     *
     * @param reqAiBase body
     */
    suspend fun getLatestGreetMsg(reqAiBase: ReqAiBase) =
        mApiAiService.getLatestGreetMsg(
            ApiAiPathUrl.PATH_GET_GREET_MSG.toFullUrlPath(),
            ApiAiHeaderMap(),
            reqAiBase
        ).await()

    /**
     * 提交用户反馈
     *
     * @param reqSubmitFeedback body
     */
    suspend fun submitFeedback(reqSubmitFeedback: ReqSubmitFeedback) =
        mApiAiService.submitFeedback(
            ApiAiPathUrl.PATH_SUBMIT_FEEDBACK.toFullUrlPath(),
            ApiAiHeaderMap(),
            reqSubmitFeedback
        ).await()

    private suspend fun <T> Call<T>.await(): T {
        return suspendCoroutine { continuation ->
            enqueue(object : Callback<T> {
                override fun onResponse(call: Call<T>, response: Response<T>) {
                    val body = response.body()
                    if (body != null) continuation.resume(body)
                    else continuation.resumeWithException(
                        RuntimeException("response body is null")
                    )
                }

                override fun onFailure(call: Call<T>, t: Throwable) {
                    continuation.resumeWithException(t)
                }
            })
        }
    }
}